<!DOCTYPE html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head><meta name="generator" content="Hexo 3.9.0">
  <meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform">
<meta http-equiv="Cache-Control" content="no-siteapp">
















  
  
  <link href="/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css">







<link href="/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css">

<link href="/css/main.css?v=5.1.4" rel="stylesheet" type="text/css">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon32.ico?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon16.ico?v=5.1.4">


  <link rel="mask-icon" href="/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="Qt,">










<meta name="description" content="在使用Qt写软件时遇到一些问题，在网上找到了一个纯C++的例子，对于理解Meta-Object System很有帮助，做个记录。">
<meta name="keywords" content="Qt">
<meta property="og:type" content="article">
<meta property="og:title" content="解释Qt的signal,slots的小例子">
<meta property="og:url" content="http://htelepathh.gitee.io/2020/11/14/解释Qt的signal-slots的小例子/index.html">
<meta property="og:site_name" content="OUTPUT">
<meta property="og:description" content="在使用Qt写软件时遇到一些问题，在网上找到了一个纯C++的例子，对于理解Meta-Object System很有帮助，做个记录。">
<meta property="og:locale" content="zh-Hans">
<meta property="og:updated_time" content="2020-11-14T13:44:15.991Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="解释Qt的signal,slots的小例子">
<meta name="twitter:description" content="在使用Qt写软件时遇到一些问题，在网上找到了一个纯C++的例子，对于理解Meta-Object System很有帮助，做个记录。">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":true},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://htelepathh.gitee.io/2020/11/14/解释Qt的signal-slots的小例子/">





  <title>解释Qt的signal,slots的小例子 | OUTPUT</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/" class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">OUTPUT</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">HTelepathH's blog</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-message">
          <a href="/message" rel="section">
            
            留言
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://htelepathh.gitee.io/2020/11/14/解释Qt的signal-slots的小例子/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="HTelepathH">
      <meta itemprop="description" content>
      <meta itemprop="image" content="/images/MOB.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="OUTPUT">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">解释Qt的signal,slots的小例子</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2020-11-14T21:12:19+08:00">
                2020-11-14
              </time>
            

            

            
          </span>

          
            <span class="post-category">
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/API/" itemprop="url" rel="index">
                    <span itemprop="name">API</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          

          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <p>在使用Qt写软件时遇到一些问题，在网上找到了一个纯C++的例子，对于理解Meta-Object System很有帮助，做个记录。<br><a id="more"></a></p>
<p><code>MetaObject</code>是<code>Object</code>的静态成员，用于记录所有<code>Object</code>及其子类的对象之间的signal和slot(字符串形式)。每个signal和slot都有自己的一个索引，由其函数名字符串在<code>MetaObject</code>中的相对索引决定。</p>
<p>每一个<code>Object</code>都拥有自己的<code>ConnectionMap</code>用与保存<strong>与自己signal连接的slot函数的对象和索引</strong>，形式为<code>&lt;signal_id,Connection&gt;</code>。Connection形式为<code>{Object* receiver, slot_id}</code>。调用<code>connect</code>时分别找到signal和slot的id，添加到sender的<code>ConnectionMap</code>中。</p>
<p>emit signal时，直接调用<code>MetaObject</code>的静态方法<code>active(Object *sender, int sig_id)</code>。<code>active</code>在sender的<code>ConnectionMap</code>中找出所有key为sig_id的<code>Connection</code>，并根据slot_id直接调用对应<code>Object</code>的槽函数(通过<code>Object::metacall</code>)。</p>
<p>显然这个例子中的<code>MetaObject</code>中的字符串，以及<code>Object::metacall</code>中的回调，在真正的应用场景下都需要预处理，这也就是MOC系统做的任务。例子中展示了最简单的同线程内connect的情况，但是基本原理已经清晰显示。还有多线程的情况以及并发的情况会更加复杂，还需要进一步研究。<br><figure class="highlight cpp"><table><tr><td class="code"><pre><span class="line"><span class="comment">//object.h</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> OBJECT_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> OBJECT_H</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;map&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;cstring&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;string&gt;</span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">//宏定义</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SLOT(a) #a</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SIGNAL(a) #a</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> cpp_slots</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> cpp_signals public</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> cpp_emit</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Object</span>;</span></span><br><span class="line"><span class="comment">//元对象系统，负责搜集信号与槽的名称</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">MetaObject</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="comment">//信号组</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *signal;</span><br><span class="line">    <span class="comment">//槽组</span></span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *slot;</span><br><span class="line">    <span class="comment">//激活某个信号,idx为信号索引</span></span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">active</span><span class="params">(Object *sender, <span class="keyword">int</span> idx)</span></span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//被连接对象信息</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Connection</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    Object *receiver; <span class="comment">//信号的接收者</span></span><br><span class="line">    <span class="keyword">int</span> method;       <span class="comment">//槽函数索引</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//保存信号索引与连接对象映射</span></span><br><span class="line"><span class="keyword">using</span> ConnectionMap   = <span class="built_in">std</span>::<span class="built_in">multimap</span>&lt;<span class="keyword">int</span>, Connection&gt;;</span><br><span class="line"><span class="keyword">using</span> ConnectionMapIt = <span class="built_in">std</span>::<span class="built_in">multimap</span>&lt;<span class="keyword">int</span>, Connection&gt;::iterator;</span><br><span class="line"></span><br><span class="line"><span class="comment">//信号和槽的索引查找函数，返回信号或槽的索引</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">int</span> <span class="title">find_string</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span> *str, <span class="keyword">const</span> <span class="keyword">char</span> *substr)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">strlen</span>(str) &lt; <span class="built_in">strlen</span>(substr))</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    <span class="keyword">int</span> idx = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> len = <span class="built_in">strlen</span>(substr);</span><br><span class="line">    <span class="keyword">bool</span> start = <span class="literal">true</span>;</span><br><span class="line">    <span class="keyword">const</span> <span class="keyword">char</span> *pos = str;</span><br><span class="line">    <span class="keyword">while</span> (*pos)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">if</span> (start &amp;&amp; !<span class="built_in">strncmp</span>(pos, substr, len) &amp;&amp; pos[len] == <span class="string">'\n'</span>)</span><br><span class="line">            <span class="keyword">return</span> idx;</span><br><span class="line">        start = <span class="literal">false</span>;</span><br><span class="line">        <span class="keyword">if</span> (*pos == <span class="string">'\n'</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            idx++;</span><br><span class="line">            start = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        pos++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Object</span></span></span><br><span class="line"><span class="class">&#123;</span></span><br><span class="line">    <span class="keyword">static</span> MetaObject meta; <span class="comment">//静态元对象声明</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">metacall</span><span class="params">(<span class="keyword">int</span> idx)</span></span>; <span class="comment">//声明元方法调用函数</span></span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    Object()</span><br><span class="line">    &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    Object(<span class="keyword">const</span> <span class="built_in">string</span>&amp; _name) : name(_name)</span><br><span class="line">    &#123;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">string</span> name;</span><br><span class="line">    <span class="comment">//建立连接</span></span><br><span class="line">    <span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">cpp_connect</span><span class="params">(Object *sender, <span class="keyword">const</span> <span class="keyword">char</span> *sig, Object *receiver, <span class="keyword">const</span> <span class="keyword">char</span> *slt)</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="comment">//从元对象数据表中查看信号和槽是否存在</span></span><br><span class="line">        <span class="keyword">int</span> sig_idx = find_string(sender-&gt;meta.signal, sig);</span><br><span class="line">        <span class="keyword">int</span> slt_idx = find_string(receiver-&gt;meta.slot, slt);</span><br><span class="line">        <span class="comment">//如果没有找到信号或者槽</span></span><br><span class="line">        <span class="keyword">if</span> (sig_idx == <span class="number">-1</span> || slt_idx == <span class="number">-1</span>)</span><br><span class="line">            perror(<span class="string">"signal or slot not found!"</span>);</span><br><span class="line">        <span class="keyword">else</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="comment">//创建一个连接，连接内存储接收者和槽函数的索引</span></span><br><span class="line">            Connection c = &#123;receiver, slt_idx&#125;;</span><br><span class="line">            <span class="built_in">cout</span> &lt;&lt;<span class="string">"add an Connection of "</span>&lt;&lt; receiver-&gt;name </span><br><span class="line">                &lt;&lt;<span class="string">" to "</span>&lt;&lt;sender-&gt;name&lt;&lt;<span class="string">" Connection map"</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">            <span class="comment">//将信号的索引和接收者的信息存储到信号发射者的map容器中</span></span><br><span class="line">            sender-&gt;connections.insert(<span class="built_in">std</span>::pair&lt;<span class="keyword">int</span>, Connection&gt;(sig_idx, c));</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">emitSignal</span><span class="params">()</span> <span class="comment">//公有测试函数，发送一个信号</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; name &lt;&lt; <span class="string">" emiting a signal..."</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">        <span class="function">cpp_emit <span class="title">valueChanged</span><span class="params">()</span></span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    cpp_signals : <span class="function"><span class="keyword">void</span> <span class="title">valueChanged</span><span class="params">()</span></span>; <span class="comment">//信号声明</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> cpp_slots : </span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">onValueChanged</span><span class="params">()</span> <span class="comment">//槽函数</span></span></span><br><span class="line"><span class="function">    </span>&#123;</span><br><span class="line">        <span class="built_in">cout</span> &lt;&lt; name &lt;&lt;<span class="string">" Value Changed."</span> &lt;&lt; <span class="built_in">endl</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">friend</span> <span class="class"><span class="keyword">class</span> <span class="title">MetaObject</span>;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    ConnectionMap connections; <span class="comment">//连接键值对</span></span><br><span class="line">    </span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">// OBJECT_H</span></span></span><br></pre></td></tr></table></figure></p>
<figure class="highlight cpp"><table><tr><td class="code"><pre><span class="line"><span class="comment">//object.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"object.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//信号的名称</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span> signalNames[] = <span class="string">"valueChanged\n"</span>;</span><br><span class="line"><span class="comment">//槽的名称</span></span><br><span class="line"><span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">char</span> slotNames[] = <span class="string">"onValueChanged\n"</span>;</span><br><span class="line"><span class="comment">//静态元对象的填充</span></span><br><span class="line">MetaObject Object::meta = &#123;signalNames, slotNames&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//元方法调用函数的实现，根据连接的索引回调槽函数</span></span><br><span class="line"><span class="keyword">void</span> Object::metacall(<span class="keyword">int</span> idx)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">switch</span> (idx)</span><br><span class="line">    &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="number">0</span>:</span><br><span class="line">        onValueChanged();</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//信号的实现</span></span><br><span class="line"><span class="keyword">void</span> Object::valueChanged()</span><br><span class="line">&#123;</span><br><span class="line">    MetaObject::active(<span class="keyword">this</span>, <span class="number">0</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//激活信号</span></span><br><span class="line"><span class="keyword">void</span> MetaObject::active(Object *sender, <span class="keyword">int</span> idx)</span><br><span class="line">&#123;</span><br><span class="line">    ConnectionMapIt it;</span><br><span class="line">    <span class="built_in">std</span>::pair&lt;ConnectionMapIt, ConnectionMapIt&gt; ret;</span><br><span class="line">    ret = sender-&gt;connections.equal_range(idx);</span><br><span class="line">    <span class="keyword">for</span> (it = ret.first; it != ret.second; ++it)</span><br><span class="line">    &#123;</span><br><span class="line">        Connection c = (*it).second;</span><br><span class="line">        c.receiver-&gt;metacall(c.method); <span class="comment">//根据索引调用元方法</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight cpp"><table><tr><td class="code"><pre><span class="line"><span class="comment">//main.cpp</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;iostream&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"object.h"</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    Object obj1("AA"), obj2("BB");</span><br><span class="line">    <span class="comment">//连接信号和槽</span></span><br><span class="line">    Object::cpp_connect(&amp;obj1, SIGNAL(valueChanged), &amp;obj2, SLOT(onValueChanged));</span><br><span class="line">    <span class="comment">//发射一个信号进行测试</span></span><br><span class="line">    obj1.emitSignal();</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/Qt/" rel="tag"># Qt</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2020/10/03/6-828-xv6-Virtual-Memory/" rel="next" title="[6.828] xv6 Virtual Memory">
                <i class="fa fa-chevron-left"></i> [6.828] xv6 Virtual Memory
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2021/03/30/Inequalities/" rel="prev" title="Inequalities">
                Inequalities <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
      <div id="sidebar-dimmer"></div>
    
    <div class="sidebar-inner">

      

      

      <section class="site-overview-wrap sidebar-panel sidebar-panel-active">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image" src="/images/MOB.jpg" alt="HTelepathH">
            
              <p class="site-author-name" itemprop="name">HTelepathH</p>
              <p class="site-description motion-element" itemprop="description">Learning by doing.</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/archives">
              
                  <span class="site-state-item-count">25</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/categories/index.html">
                  <span class="site-state-item-count">12</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/tags/index.html">
                  <span class="site-state-item-count">15</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="99088577@qq.com" target="_blank" title="Mail">
                      Mail</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://gitee.com/htelepathh" target="_blank" title="Gitee">
                      Gitee</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://github.com/htlpt" target="_blank" title="GitHub">
                      GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://weibo.com/u/6207125886" target="_blank" title="微博">
                      微博</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="https://www.zhihu.com/people/huang-he-tu" target="_blank" title="知乎">
                      知乎</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2022</span>
  <span class="with-love">
    <i class="fa fa-angle-double-left"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">HTelepathH</span>

  
</div>




        







        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.4"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  





  

  

  

  
  

  
  


  

  

</body>
</html>
